#pragma once
#include "cell.h"
#include "ruleset.h"
#include "nbmask.h"

template <typename T>
class CA
{
private:
	Cell<T> cell[ROWNUM][COLNUM];
	RuleSet<T> ruleset;
	NBMask nbmask;
	int timeStep;
	//vector<T>& nbValues (int row, int col) const;
	vector<T>& nbValues (const Coordinate& coo) const;
	//bool outOfBorders (int row, int col) const;
	bool outOfBorders (const Coordinate& coo) const;
	void loadState (const T**);
public:
	CA();
	CA<T>(const CA<T>& other);
	CA<T>(RuleSet<T> r, const NBMask n);
	CA<T>(const T** init, const RuleSet<T>& r, const NBMask n);
	void advance();
	T** state(int t) const;//returns the state at time = t
	T** state(void) const; //returns the current state
	T cellState (int row, int col, int time) const;
	T cellState (int row, int col) const;
	int getTime() const;
	RuleSet<T>& getRuleSet() const;
	NBMask& getNBMask() const;
	void reset();
	void reset(const T** init);

	friend ostream& operator<< (ostream& os, const CA<T>& ca);
};